﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using OwnZTec.LojaDelivery.Impressao;
using OwnZTec.LojaDelivery.Data;

namespace OwnZTec.LojaDelivery.UI.WinForms
{
    public partial class RptDesperdicio : OwnZForm
    {
        #region -- Membros e Construtores -------------------------------------------------------------------------------------------------
        public RptDesperdicio()
        {
            InitializeComponent();
        }

        private tbDesperdicioDetalhe DespDetalhe { get; set; }
        private tbDesperdicio Desperdicio { get; set; }

        #endregion ------------------------------------------------------------------------------------------------------------------------

        #region -- Eventos ----------------------------------------------------------------------------------------------------------------
        private void dtpDataFinal_ValueChanged(object sender, EventArgs e)
        {
            //Se data final for maior que hoje
            if (dtpDataFinal.Value > DateTime.Now)
            {
                MessageBox.Show("Data Final não pode ser maior do que hoje", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
                dtpDataFinal.Value = DateTime.Now;
            }

            //Se a data inicial for maior que a data Final
            if (dtpDataFinal.Value < dtpDataInicial.Value)
            {
                dtpDataInicial.Value = dtpDataFinal.Value;
            }
        }

        private void rbPeriodo_CheckedChanged(object sender, EventArgs e)
        {
            pnlPeriodo.Visible = true;
            pnlData.Visible = pnlMes.Visible = false;
        }

        private void rbMes_CheckedChanged(object sender, EventArgs e)
        {
            pnlMes.Visible = true;
            pnlData.Visible = pnlPeriodo.Visible = false;
        }

        private void rbData_CheckedChanged(object sender, EventArgs e)
        {
            pnlData.Visible = true;
            pnlMes.Visible = pnlPeriodo.Visible = false;
        }

        private void rbTotal_CheckedChanged(object sender, EventArgs e)
        {
            pnlGrupo.Visible = false;
            pnlProduto.Visible = false;
        }

        private void rbGrupo_CheckedChanged(object sender, EventArgs e)
        {
            pnlGrupo.Visible = true;
            pnlProduto.Visible = false;
        }

        private void rbProduto_CheckedChanged(object sender, EventArgs e)
        {
            pnlGrupo.Visible = false;
            pnlProduto.Visible = true;
        }

        private void RptDesperdicio_Load(object sender, EventArgs e)
        {
            Contexto.MainForm.Cursor = Cursors.Arrow;

            cboPeriodo.SelectedIndex = 0;

            //Populando Combobox de Ano
            for (int i = DateTime.Now.Year; i >= DateTime.Now.Year - 5; i--)
            {
                cboAno.Items.Add(i.ToString());
            }
            cboAno.SelectedIndex = 0;
            MesDS = geraMes();
            cboMes.DisplayMember = "sMes";
            cboMes.ValueMember = "idMes";
            cboMes.DataSource = MesDS;

            cboMes.SelectedIndex = 0;

            pnlPeriodo.Visible = true;
            pnlData.Visible = pnlGrupo.Visible = pnlMes.Visible = pnlProduto.Visible = false;

            //populando comboGrupos
            cboGrupo.DataSource = Contexto.Db.tbGrupoProdutoes.OrderBy(p => p.desNomeGrupo);
            cboGrupo.ValueMember = "idGrupo";
            cboGrupo.DisplayMember = "desNomeGrupo";

            //populando comboProdutos
            cboProduto.DataSource = Contexto.Db.tbProdutoes.Where(p => p.flgAtivo == true).OrderBy(p => p.desNomeProduto);
            cboProduto.ValueMember = "idProduto";
            cboProduto.DisplayMember = "desNomeProduto";

        }

        private void dtpDataInicial_ValueChanged(object sender, EventArgs e)
        {
            //Se a data inicial for maior que a data Final
            if (dtpDataFinal.Value < dtpDataInicial.Value)
            {
                dtpDataFinal.Value = dtpDataInicial.Value;
            }
        }

        private void btnEmitir_Click(object sender, EventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            sb = MontaRelatorio();

            if (qtdeTotal > 0)
            {
                Impressao.Impressao imprime = new Impressao.Impressao();
                imprime.ImprimeDesperdicio(sb);
            }
            else
            {
                //Mensagem que não existem registros
                MessageBox.Show("Não existem desperdícios para os filtros selecionados!", "Aviso", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        private void btnMostra_Click(object sender, EventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            sb = MontaRelatorio();

            if (qtdeTotal > 0)
            {
                var frm = new FrmMostraTela
                {
                    Pai = this
                };
                frm.sbImprime = sb;
                frm.ShowDialog();
            }
            else
            {
                //Mensagem que não existem registros
                MessageBox.Show("Não existem desperdícios para os filtros selecionados!", "Aviso", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        private void chkProduto_CheckedChanged(object sender, EventArgs e)
        {
            cboProduto.Enabled = chkProduto.Checked;
        }

        private void chkGrupo_CheckedChanged(object sender, EventArgs e)
        {
            cboGrupo.Enabled = chkGrupo.Checked;
        }

        #endregion ------------------------------------------------------------------------------------------------------------------------

        #region -- Metodos ----------------------------------------------------------------------------------------------------------------

        private StringBuilder MontaRelatorio()
        {
            // StringBuilder para fazer o texto a ser impresso
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("              Salgados Celia              ");
            sb.AppendLine("======== Relatorio de Desperdicio ========");
            sb.AppendLine("Filtros Utilizados:");
            //Inserindo os Filtros
            //Tipo
            if (rbProduto.Checked)
            {
                if (chkProduto.Checked)
                {
                    sb.AppendLine("Pesquisa por Produto Especifico");
                    sb.AppendLine(cboProduto.Text);
                }
                else
                    sb.AppendLine("Pesquisa por Produto");
            }
            else if (rbGrupo.Checked)
            {
                if (chkGrupo.Checked)
                {
                    sb.AppendLine("Pesquisa por Grupo Especifico:");
                    sb.AppendLine(cboGrupo.Text);
                }
                else
                    sb.AppendLine("Pesquisa por Grupo");
            }
            else if (rbTotal.Checked)
            {
                sb.AppendLine("Pesquisa Total");
            }
            //Período
            if (rbData.Checked)
            {
                sb.AppendLine("Por data");
                sb.AppendLine("De " + dtpDataInicial.Value.ToShortDateString() + " a " + dtpDataFinal.Value.ToShortDateString());
            }
            else if (rbMes.Checked)
            {
                sb.AppendLine("Por Mes");
                sb.AppendLine("Mes: " + cboMes.Text + " de " + cboAno.Text);
            }
            else if (rbPeriodo.Checked)
            {
                switch (cboPeriodo.SelectedIndex)
                {
                    case 0: //Hoje
                        sb.AppendLine("Hoje");
                        sb.AppendLine(DateTime.Now.ToShortDateString());
                        break;
                    case 1: //7 dias
                        sb.AppendLine("7 ultimos dias");
                        sb.AppendLine("De " + DateTime.Now.AddDays(-7).ToShortDateString() + " a " + DateTime.Now.ToShortDateString());
                        break;
                    case 2:// 15 dias
                        sb.AppendLine("15 ultimos dias");
                        sb.AppendLine("De " + DateTime.Now.AddDays(-15).ToShortDateString() + " a " + DateTime.Now.ToShortDateString());
                        break;
                    case 3://30 dias
                        sb.AppendLine("30 ultimos dias");
                        sb.AppendLine("De " + DateTime.Now.AddDays(-30).ToShortDateString() + " a " + DateTime.Now.ToShortDateString());
                        break;
                }
            }
            sb.AppendLine("=========================================");
            //Final cabeçalho

            DateTime hoje = Convert.ToDateTime(DateTime.Now.ToShortDateString());

            //Lista Desperdício
            List<tbDesperdicio> listaDesp = new List<tbDesperdicio>();
            tbDesperdicio Desp = new tbDesperdicio();

            //Inserindo tudo na lista Desperdício
            foreach (OwnZTec.LojaDelivery.Data.tbDesperdicio item in Contexto.Db.tbDesperdicios.ToList())
            {
                Desp = new tbDesperdicio();
                Desp.idDesperdicio = item.idDesperdicio;
                Desp.dtDesperdicio = item.dtDesperdicio;
                Desp.qtde = item.qtde;
                listaDesp.Add(item);
            }

            if (rbData.Checked)
            {
                listaDesp = (List<tbDesperdicio>)listaDesp.FindAll(p => p.dtDesperdicio >= dtpDataInicial.Value).FindAll(p => p.dtDesperdicio <= dtpDataFinal.Value);
            }
            else if (rbMes.Checked)
            {
                int mes;
                if (!Int32.TryParse(cboMes.SelectedValue.ToString(), out mes))
                {
                    cboMes.SelectedIndex = DateTime.Now.Month;
                }
                string dataCombo = "01/" + cboMes.SelectedItem.ToString() + "/" + cboAno.Text;
                listaDesp = (List<tbDesperdicio>)listaDesp.FindAll(p => p.dtDesperdicio.Month == Convert.ToDateTime(dataCombo).Month);
            }
            else
            {
                switch (cboPeriodo.SelectedIndex)
                {
                    case 0: //Hoje
                        listaDesp = (List<tbDesperdicio>)listaDesp.FindAll(p => p.dtDesperdicio >= hoje);
                        break;
                    case 1: //7 dias
                        listaDesp = (List<tbDesperdicio>)listaDesp.FindAll(p => p.dtDesperdicio >= hoje.AddDays(-7));
                        break;
                    case 2:// 15 dias
                        listaDesp = (List<tbDesperdicio>)listaDesp.FindAll(p => p.dtDesperdicio >= hoje.AddDays(-15));
                        break;
                    case 3://30 dias
                        listaDesp = (List<tbDesperdicio>)listaDesp.FindAll(p => p.dtDesperdicio >= hoje.AddDays(-30));
                        break;
                }
            }

            listaDetalhesFull = new List<tbDesperdicioDetalhe>();
            foreach (tbDesperdicio item in listaDesp)
            {
                listaDetalhesFull.AddRange(Contexto.Db.tbDesperdicioDetalhes.Where(p => p.idDesperdicio == item.idDesperdicio).ToList());
            }

            if (listaDesp.Count > 0)
            {
                if (rbTotal.Checked)//Evento para chamar Total
                    sb = InserePorTotal(listaDesp, sb);
                else if (rbGrupo.Checked)
                {//Evento para chamar Por Grupo
                    if (chkGrupo.Checked)
                        sb = InserePorGrupoEspecifico(listaDesp, sb);
                    else
                        sb = InserePorGrupo(listaDesp, sb);
                }
                else if (rbProduto.Checked)
                {//Evento para chamar Por Produto
                    if (chkProduto.Checked)
                        sb = InserePorProdutoEspecifico(listaDesp, sb);
                    else
                        sb = InserePorProduto(listaDesp, sb);
                }

                sb.AppendLine("=========================================");
            }

            return sb;
        }

        int qtdeTotal;

        List<tbDesperdicioDetalhe> listaDetalhesFull;

        private StringBuilder InserePorProdutoEspecifico(List<tbDesperdicio> listaDesp, StringBuilder sb)
        {
            qtdeTotal = 0;
            int qtdeProdutoTotal = 0;
            string ProdutoNome = string.Empty;
            bool primeira = true;
            listaDetalhesFull = new List<tbDesperdicioDetalhe>();

            foreach (tbDesperdicio item in listaDesp.OrderBy(x=>x.dtDesperdicio))
            {
                if (!primeira)
                    sb.AppendLine("=========================================");
                listaDetalhesFull = (Contexto.Db.tbDesperdicioDetalhes.Where(p => p.idDesperdicio == item.idDesperdicio).ToList());

                var detalhes =
                    from listaDetalhe in listaDetalhesFull
                    where listaDetalhe.idProduto == Convert.ToInt32(cboProduto.SelectedValue)
                    group listaDetalhe by listaDetalhe.idGrupo into newGroup
                    select newGroup;

                foreach (var detalhe in detalhes)
                {
                    foreach (var produto in detalhe)
                    {
                        sb.AppendLine("Data: " + item.dtDesperdicio.ToShortDateString());
                        qtdeProdutoTotal = produto.qtde;
                        qtdeTotal += qtdeProdutoTotal;
                        ProdutoNome = Contexto.Db.tbProdutoes.ToList().Find(x => x.idProduto == produto.idProduto.ParaInt()).desNomeProduto;
                        sb.AppendLine("Total : " + qtdeProdutoTotal.ToString());
                    }
                    primeira = false;
                }
            }

            sb.AppendLine("=========================================");
            sb.AppendLine("Total da Pesquisa: " + qtdeTotal.ToString());
            return sb;
        }

        private StringBuilder InserePorProduto(List<tbDesperdicio> listaDesp, StringBuilder sb)
        {
            qtdeTotal = 0;
            int qtdeGrupoTotal = 0;
            int qtdeProdutoTotal = 0;
            string grupoNome = string.Empty;
            string ProdutoNome = string.Empty;
            bool primeira = true;
            listaDetalhesFull = new List<tbDesperdicioDetalhe>();

            foreach (tbDesperdicio item in listaDesp.OrderBy(x => x.dtDesperdicio))
            {
                if (!primeira)
                    sb.AppendLine("=========================================");
                sb.AppendLine("Data: " + item.dtDesperdicio.ToShortDateString());

                listaDetalhesFull = (Contexto.Db.tbDesperdicioDetalhes.Where(p => p.idDesperdicio == item.idDesperdicio).ToList());

                var detalhes =
                    from listaDetalhe in listaDetalhesFull
                    group listaDetalhe by listaDetalhe.idGrupo into newGroup
                    select newGroup;

                foreach (var detalhe in detalhes)
                {
                    qtdeGrupoTotal = detalhe.Sum(p => p.qtde);
                    grupoNome = Contexto.Db.tbGrupoProdutoes.ToList().Find(x => x.idGrupo == detalhe.First().idGrupo.ParaInt()).desNomeGrupo;
                    if (!primeira)
                        sb.AppendLine("*****");
                    sb.AppendLine("Grupo: " + grupoNome);
                    sb.AppendLine("Total do Grupo : " + qtdeGrupoTotal.ToString());
                    sb.AppendLine("*****");
                    foreach (var produto in detalhe)
                    {
                        qtdeProdutoTotal = produto.qtde;
                        qtdeTotal += qtdeProdutoTotal;
                        ProdutoNome = Contexto.Db.tbProdutoes.ToList().Find(x => x.idProduto == produto.idProduto.ParaInt()).desNomeProduto;
                        sb.AppendLine("Produto: " + ProdutoNome);
                        sb.AppendLine("Total do Produto : " + qtdeProdutoTotal.ToString());
                    }
                    primeira = false;
                }
            }

            sb.AppendLine("=========================================");
            sb.AppendLine("Total da Pesquisa: " + qtdeTotal.ToString());
            return sb;
        }

        private StringBuilder InserePorGrupo(List<tbDesperdicio> listaDesp, StringBuilder sb)
        {
            qtdeTotal = 0;
            int qtdeGrupoTotal = 0;
            string grupoNome = string.Empty;
            bool primeira = true;
            listaDetalhesFull = new List<tbDesperdicioDetalhe>();

            foreach (tbDesperdicio item in listaDesp.OrderBy(x => x.dtDesperdicio))
            {
                if (!primeira)
                    sb.AppendLine("=========================================");
                sb.AppendLine("Data: " + item.dtDesperdicio.ToShortDateString());

                listaDetalhesFull = (Contexto.Db.tbDesperdicioDetalhes.Where(p => p.idDesperdicio == item.idDesperdicio).ToList());

                var detalhes =
                        from listaDetalhe in listaDetalhesFull
                        group listaDetalhe by listaDetalhe.idGrupo into newGroup
                        select newGroup;

                foreach (var detalhe in detalhes)
                {
                    qtdeGrupoTotal = detalhe.Sum(p => p.qtde);
                    qtdeTotal += qtdeGrupoTotal;
                    grupoNome = Contexto.Db.tbGrupoProdutoes.ToList().Find(x => x.idGrupo == detalhe.First().idGrupo.ParaInt()).desNomeGrupo;

                    sb.AppendLine("Grupo: " + grupoNome);
                    sb.AppendLine("Total do Grupo : " + qtdeGrupoTotal.ToString());
                }
                primeira = false;
            }

            sb.AppendLine("=========================================");
            sb.AppendLine("Total da Pesquisa: " + qtdeTotal.ToString());
            return sb;
        }

        private StringBuilder InserePorGrupoEspecifico(List<tbDesperdicio> listaDesp, StringBuilder sb)
        {
            qtdeTotal = 0;
            int qtdeGrupoTotal = 0;
            bool primeira = true;
            listaDetalhesFull = new List<tbDesperdicioDetalhe>();

            foreach (tbDesperdicio item in listaDesp.OrderBy(x => x.dtDesperdicio))
            {
                if (!primeira)
                    sb.AppendLine("=========================================");

                listaDetalhesFull = (Contexto.Db.tbDesperdicioDetalhes.Where(p => p.idDesperdicio == item.idDesperdicio).ToList());

                var detalhes =
                    from listaDetalhe in listaDetalhesFull
                    where listaDetalhe.idGrupo == Convert.ToInt32(cboGrupo.SelectedValue)
                    group listaDetalhe by listaDetalhe.idGrupo into newGroup
                    select newGroup;

                foreach (var detalhe in detalhes)
                {
                    sb.AppendLine("Data: " + item.dtDesperdicio.ToShortDateString());
                    qtdeGrupoTotal = detalhe.Sum(p => p.qtde);
                    qtdeTotal += qtdeGrupoTotal;
                    sb.AppendLine("Total do Grupo : " + qtdeGrupoTotal.ToString());
                }
                primeira = false;
            }

            sb.AppendLine("=========================================");
            sb.AppendLine("Total da Pesquisa: " + qtdeTotal.ToString());
            return sb;
        }

        private StringBuilder InserePorTotal(List<tbDesperdicio> listaDesp, StringBuilder sb)
        {
            qtdeTotal = listaDesp.Sum(p => p.qtde);
            bool primeira = true;

            foreach (tbDesperdicio item in listaDesp.OrderBy(x => x.dtDesperdicio))
            {
                if (!primeira)
                    sb.AppendLine("=========================================");
                sb.AppendLine("Data: " + item.dtDesperdicio.ToShortDateString());
                sb.AppendLine("Total do dia:" + item.qtde.ToString());
                primeira = false;
            }

            sb.AppendLine("=========================================");
            sb.AppendLine("Total da Pesquisa: " + qtdeTotal.ToString());
            return sb;
        }

        private List<Meses> MesDS;
        private List<Meses> geraMes()
        {
            List<Meses> lista = new List<Meses>();
            Meses item = new Meses();
            string[] mes = { "-- Selecione --", "Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro" };
            for (int i = 0; i<=12;i++)
            {
                item = new Meses();
                item.idMes = i;
                item.sMes = mes[i];
                lista.Add(item);
            }
            return lista;
        }

        #endregion ------------------------------------------------------------------------------------------------------------------------

    }

    public class Meses
    {
        public int idMes { get; set; }
        public string sMes { get; set; }
    }
}
